/**
 * Copyright (C) 2023 maminjie <canpool@163.com>
 * Copyright (C) 2022 Syarif Fakhri
 * Copyright (C) 2017 Uwe Kindler
 * SPDX-License-Identifier: LGPL-2.1
 **/
#pragma once

#include "QxDockAutoHideTab.h"
#include "QxDockGlobal.h"
#include <QScrollArea>

class QXmlStreamWriter;

QX_BEGIN_NAMESPACE

struct DockAutoHideSideBarPrivate;
class DockContainerWidgetPrivate;
class DockContainerWidget;
class DockAutoHideTab;
class DockAutoHideContainer;
class DockStateReader;

/**
 * Side tab bar widget that is shown at the edges of a dock container.
 * The tab bar is only visible, if it contains visible content, that means if
 * it contains visible tabs. If it is empty or all tabs are hidden, then the
 * side bar is also hidden. As soon as one single tab becomes visible, this
 * tab bar will be shown.
 * The DockAutoHideSideBar uses a QScrollArea here, to enable proper resizing.
 * If the side bar contains many tabs, then the tabs are simply clipped - this
 * is the same like in visual studio
 */
class QX_DOCK_EXPORT DockAutoHideSideBar : public QScrollArea
{
    Q_OBJECT
    Q_PROPERTY(int sideBarLocation READ sideBarLocation)
    Q_PROPERTY(Qt::Orientation orientation READ orientation)
    Q_PROPERTY(int spacing READ spacing WRITE setSpacing)
private:
    DockAutoHideSideBarPrivate *d;   ///< private data (pimpl)
    friend struct DockAutoHideSideBarPrivate;
    friend class DockWidgetSideTab;
    friend DockContainerWidgetPrivate;
    friend DockContainerWidget;
protected:
    virtual bool eventFilter(QObject *watched, QEvent *event) override;

    /**
     * Saves the state into the given stream
     */
    void saveState(QXmlStreamWriter &Stream) const;

    /**
     * Inserts the given dock widget tab at the given position.
     * An Index value of -1 appends the side tab at the end.
     */
    void insertTab(int Index, DockAutoHideTab *SideTab);
public:
    using Super = QScrollArea;

    /**
     * Default Constructor
     */
    DockAutoHideSideBar(DockContainerWidget *parent, SideBarLocation area);

    /**
     * Virtual Destructor
     */
    virtual ~DockAutoHideSideBar();

    /**
     * Removes the given DockWidgetSideTab from the tabbar
     */
    void removeTab(DockAutoHideTab *SideTab);

    /**
     * Insert dock widget into the side bar.
     * The function creates the auto hide dock container, inserts the
     * auto hide tab
     */
    DockAutoHideContainer *insertDockWidget(int Index, DockWidget *dockWidget);

    /**
     * Removes the auto hide widget from this side bar
     */
    void removeAutoHideWidget(DockAutoHideContainer *AutoHideWidget);

    /**
     * Adds the given AutoHideWidget to this sidebar.
     * If the AutoHideWidget is in another sidebar, then it will be removed
     * from this sidebar.
     */
    void addAutoHideWidget(DockAutoHideContainer *AutoHideWidget);

    /**
     * Returns orientation of side tab.
     */
    Qt::Orientation orientation() const;

    /*
     * get the side tab widget at position, returns nullptr if it's out of bounds
     */
    DockAutoHideTab *tabAt(int index) const;

    /*
     * Gets the count of the tab widgets
     */
    int tabCount() const;

    /**
     * Getter for side tab bar area property
     */
    SideBarLocation sideBarLocation() const;

    /**
     * Overrides the minimumSizeHint() function of QScrollArea
     * The minimumSizeHint() is bigger than the sizeHint () for the scroll
     * area because even if the scrollbars are invisible, the required speace
     * is reserved in the minimumSizeHint(). This override simply returns
     * sizeHint();
     */
    virtual QSize minimumSizeHint() const override;

    /**
     * The function provides a sizeHint that matches the height of the
     * internal viewport.
     */
    virtual QSize sizeHint() const override;

    /**
     * Getter for spacing property - returns the spacing of the tabs
     */
    int spacing() const;

    /**
     * Setter for spacing property - sets the spacing
     */
    void setSpacing(int Spacing);

    /**
     * Returns the dock container that hosts this sideBar()
     */
    DockContainerWidget *dockContainer() const;
};

QX_END_NAMESPACE
